package CryptoPrim;

import Utils.ByteTree;
import ArithUtils.*;
import ArithmeticObjects.*;

/**
 * A class which represents a RM Group (Rw)
 * 
 * @author Itamar Carmel, amirzell
 */
public class RandomizerGroup {

	private BTField<BigNumber> Zq; // Field of elements of Rw (Mw = Zq^w)
	private int width; // width of the group (w)
	
	/**
	 * Constructor for RM Group from given field of elements (Zq) and
	 * the width (w) of elements.
	 * 
	 * @param Zq
	 * @param width
	 */
	public RandomizerGroup(BTField <BigNumber> Zq, int width) {
		this.Zq = Zq;
		this.width = width;
	}

	/**
	 * Unary operation which returns the given RM's additive inverse.
	 * 
	 * @param rm
	 * @return -(rm)
	 */
	public Randomizer addInverse(Randomizer rm) {
		Randomizer ret = new Randomizer();
		for (int i=0; i < this.width; i++){
			ret.add(Zq.addInverse(rm.get(i)));
		}
		return ret;
	}

	/**
	 * Converts BT to it's RM rep.
	 * 
	 * @param bt
	 * @return RM(bt)
	 */
	public Randomizer BTToRandomizer(ByteTree bt) {
		Array<BTField<BigNumber>.BTElement> arr = new Array<BTField<BigNumber>.BTElement>();
		if (this.width == 1){
			arr.add(Zq.getElement(bt));
		} else{
			arr = Zq.getElementArray(bt);
		}
		return new Randomizer(arr);
	}

	/**
	 * Converts RM to it's BT rep.
	 * 
	 * @param rm
	 * @return BT(rm)
	 */
	public ByteTree randomizerToBT(Randomizer rnd){
		if (this.width == 1){
			return Zq.ElementToByteTree(rnd.getArr().get(0));
		} else{
			return Zq.toByteTree(rnd.getArr());
		}
	}
	
}
